import wave
import numpy as np
import os

def wav_to_c_array(wav_filename, output_filename):
    with wave.open(wav_filename, 'rb') as wav_file:
        # 获取音频参数
        num_channels = wav_file.getnchannels()
        sample_width = wav_file.getsampwidth()
        sample_rate = wav_file.getframerate()
        num_frames = wav_file.getnframes()

        # 读取音频数据
        audio_data = wav_file.readframes(num_frames)
        if sample_width == 1:
            audio_array = np.frombuffer(audio_data, dtype=np.uint8)  # 假设样本宽度为8位
            # 将音频数据转换为16进制的C语言数组格式
            c_array = ", ".join(f"0x{val:02X}" for val in audio_array)
        elif sample_width == 2:
            audio_array = np.frombuffer(audio_data, dtype=np.uint16)  # 假设样本宽度为16位
            # 将音频数据转换为16进制的C语言数组格式
            c_array = ", ".join(f"0x{val:04X}" for val in audio_array)

        wave_filename_without_extension = os.path.splitext(os.path.basename(wav_filename))[0]
        array_length_name = wave_filename_without_extension + "_length"
        include_file_name = wave_filename_without_extension + ".h"
        # 创建C语言数组字符串
        if sample_width == 1:
            c_code = "/***************************\n"
            c_code += f"\tWAV file: {wav_filename}"
            c_code += f"\tChannels: {num_channels}"
            c_code += f"\tSample rate: {sample_rate}"
            c_code += f"\tSample width: {sample_width} bytes"
            c_code += f"\tNumber of frames: {num_frames}"
            c_code += "***************************/\n"
            c_code += f'#include "{include_file_name}"\n'
            c_code += f"\nconst uint8_t {wave_filename_without_extension}[] = {{\n"
            c_code += f"\t{c_array}\n"
            c_code += "};\n\n"
            c_code += f"uint16_t {array_length_name} = sizeof({wave_filename_without_extension}) / sizeof({wave_filename_without_extension}[0]);\n"
        elif sample_width == 2:
            c_code = "/***************************\n"
            c_code += f"\tWAV file: {wav_filename}\n"
            c_code += f"\tChannels: {num_channels}\n"
            c_code += f"\tSample rate: {sample_rate}\n"
            c_code += f"\tSample width: {sample_width} bytes\n"
            c_code += f"\tNumber of frames: {num_frames}\n"
            c_code += "***************************/\n"
            c_code += f'#include "{include_file_name}"\n'
            c_code += f"\nconst uint16_t {wave_filename_without_extension}[] = {{\n"
            c_code += f"\t{c_array}\n"
            c_code += "};\n\n"
            c_code += f"uint16_t {array_length_name} = sizeof({wave_filename_without_extension}) / sizeof({wave_filename_without_extension}[0]);\n"



        # 将C语言数组写入文件
        with open(output_filename, 'w') as output_file:
            output_file.write(c_code)

        h_header = wave_filename_without_extension.upper()
        h_code = f"#ifndef _{h_header}_H_\n"
        h_code += f"#define _{h_header}_H_\n"
        h_code += "\n#include <stdint.h>\n"
        h_code += "#include <stddef.h>\n"
        if sample_width == 1:
            h_code += f"\nextern const uint8_t {wave_filename_without_extension}[];\n"
        elif sample_width == 2:
            h_code += f"\nextern const uint16_t {wave_filename_without_extension}[];\n"
        h_code += f"extern uint16_t {array_length_name};\n"
        h_code += "\n#endif\n"

        include_full_name = os.path.join(os.getcwd(), include_file_name)
        with open(include_full_name, 'w') as output_file:
            output_file.write(h_code)

        print(f"Converted {wav_filename} to C array in {output_filename}\n")

# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    while True:
        file_name = input("Please Enter the file name of WAV: ")
        if ".wav" not in file_name:
            file_name += ".wav"
        curren_dir = os.getcwd()
        wav_full_name = os.path.join(curren_dir, file_name)
        output_wave_name = os.path.splitext(os.path.basename(file_name))[0]
        output_wave_name += ".c"
        output_full_name = os.path.join(curren_dir, output_wave_name)
        wav_to_c_array(wav_full_name, output_full_name)

        text = input("Please Press q to Exit: ")
        if text.upper() == 'Q':
            break


        # wav_to_c_array('baby_squeak_toy_2.wav', 'baby_squeak_toy_2.c')
        # wav_to_c_array('bloop_1.wav', 'bloop_1.c')
        # wav_to_c_array('bloop_2.wav', 'bloop_2.c')
        # wav_to_c_array('fart.wav', 'fart.c')
        # wav_to_c_array('frog_qua_cry.wav', 'frog_qua_cry.c')
        # wav_to_c_array('futuristic_gun_shot.wav', 'futuristic_gun_shot.c')
        # wav_to_c_array('human_shortfart.wav', 'human_shortfart.c')
        # wav_to_c_array('keyboard_chspsil.wav', 'keyboard_chspsil.c')
        # wav_to_c_array('keyboard5.wav', 'keyboard5.c')
        # wav_to_c_array('mech_keyboard02.wav', 'mech_keyboard02.c')
        # wav_to_c_array('pop_horns_fall_emaj.wav', 'pop_horns_fall_emaj.c')
        # wav_to_c_array('pop_horns_fall_fmin7.wav', 'pop_horns_fall_fmin7.c')
        # wav_to_c_array('reload.wav', 'reload.c')
        # wav_to_c_array('rubber_chicken_squeak_toy.wav', 'rubber_chicken_squeak_toy.c')
        # wav_to_c_array('short_fart.wav', 'short_fart.c')
        # wav_to_c_array('small_realpoot.wav', 'small_realpoot.c')
        # wav_to_c_array('squeaky_toy_1.wav', 'squeaky_toy_1.c')
        # wav_to_c_array('sw_tootoo.wav', 'sw_tootoo.c')